package callBack

import (
	"encoding/json"
	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/connector/redis"
	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/filesystem"
	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/filesystem/driver/oss"
	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/gin/log"
	model "gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/models"
	"gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/serializer"
	"github.com/gin-gonic/gin"
	"net/http"
)

const (
	CallbackFailedStatusCode = http.StatusUnauthorized
)

// 阿里云
// 对上传会话进行验证
func UseUploadSession(policyType string) gin.HandlerFunc {
	return func(c *gin.Context) {
		// 验证key并查找用户
		log.Info("【oss回调】验证key并查找用户, policyType:", policyType)
		resp := uploadCallbackCheckV1(c, policyType)
		if resp.Code != 0 {
			log.Error("【oss回调】err (resp.Code != 0),resp:", resp)
			c.JSON(CallbackFailedStatusCode, resp)
			c.Abort()
			return
		}

		c.Next()
	}
}

// uploadCallbackCheck 对上传回调请求的 callback key 进行验证，如果成功则返回上传用户
func uploadCallbackCheck(c *gin.Context, policyType string) serializer.Response {
	// 验证 Callback Key
	sessionID := c.Param("sessionID")
	if sessionID == "" {
		log.Error("【oss回调】Session ID 不能为空")
		return serializer.ParamErr("Session ID 不能为空", nil)
	}

	callbackSessionRaw, err := redis.ImRedisDB.Get(filesystem.UploadSessionCachePrefix + sessionID).Bytes()
	if err != nil {
		log.Error("获取缓存数据失败，err:", err.Error())
		return serializer.Err(serializer.CodePolicyNotAllowed, "会话数据不存在", nil)
	}
	var callbackSession serializer.UploadSession
	if err := json.Unmarshal(callbackSessionRaw, &callbackSession); err != nil {
		//if err := callbackSessionRaw.Scan(&callbackSession); err != nil {
		log.Error("凡序列化失败，err:", err.Error())
		return serializer.Err(serializer.CodePolicyNotAllowed, "反序列化失败", nil)
	}
	c.Set(filesystem.UploadSessionCtx, &callbackSession)
	if callbackSession.Policy.Type != policyType {
		log.Error("【oss回调】Policy not supported， callbackSession.Policy.Type："+callbackSession.Policy.Type+"，policyType：", policyType)
		return serializer.Err(serializer.CodePolicyNotAllowed, "Policy not supported", nil)
	}

	// 清理回调会话
	_ = redis.ImRedisDB.Del(filesystem.UploadSessionCachePrefix + sessionID)
	//_ = cache.GetRedisStore().Delete([]string{sessionID}, filesystem.UploadSessionCachePrefix)
	// 查找用户
	//user, err := model.GetActiveUserByID(callbackSession.UID)
	//if err != nil {
	//	return serializer.Err(serializer.CodeCheckLogin, "找不到用户", err)
	//}
	var user model.User
	user.ID = callbackSession.UID
	c.Set(filesystem.UserCtx, &user)
	return serializer.Response{}
}

// uploadCallbackCheck 对上传回调请求的 callback key 进行验证，如果成功则返回上传用户
func uploadCallbackCheckV1(c *gin.Context, policyType string) serializer.Response {
	// 验证 Callback Key
	sessionID := c.Param("sessionID")
	if sessionID == "" {
		log.Error("【oss回调】Session ID 不能为空")
		return serializer.ParamErr("Session ID 不能为空", nil)
	}

	callbackSessionRaw, err := redis.AliyunRedisDB.Get(filesystem.UploadSessionCachePrefix + sessionID).Bytes()
	if err != nil {
		log.Error("获取缓存数据失败，err:", err.Error())
		return serializer.Err(serializer.CodePolicyNotAllowed, "会话数据不存在", nil)
	}
	var callbackSession serializer.UploadSession
	if err = json.Unmarshal(callbackSessionRaw, &callbackSession); err != nil {
		//if err := callbackSessionRaw.Scan(&callbackSession); err != nil {
		log.Error("凡序列化失败，err:", err.Error())
		return serializer.Err(serializer.CodePolicyNotAllowed, "反序列化失败", nil)
	}
	c.Set(filesystem.UploadSessionCtx, &callbackSession)
	if callbackSession.Policy.Type != policyType {
		log.Error("【oss回调】Policy not supported， callbackSession.Policy.Type："+callbackSession.Policy.Type+"，policyType：", policyType)
		return serializer.Err(serializer.CodePolicyNotAllowed, "Policy not supported", nil)
	}

	// 清理回调会话
	_ = redis.AliyunRedisDB.Del(filesystem.UploadSessionCachePrefix + sessionID)
	//_ = cache.GetRedisStore().Delete([]string{sessionID}, filesystem.UploadSessionCachePrefix)
	// 查找用户
	//user, err := model.GetActiveUserByID(callbackSession.UID)
	//if err != nil {
	//	return serializer.Err(serializer.CodeCheckLogin, "找不到用户", err)
	//}
	var user model.User
	user.ID = callbackSession.UID
	c.Set(filesystem.UserCtx, &user)
	return serializer.Response{}
}

// OSSCallbackAuth 阿里云OSS回调签名验证
func OSSCallbackAuth() gin.HandlerFunc {
	return func(c *gin.Context) {
		err := oss.VerifyCallbackSignature(c.Request)
		if err != nil {
			log.Error("回调签名验证失败，err: %s", err)
			c.JSON(401, serializer.GeneralUploadCallbackFailed{Error: "回调签名验证失败, err:" + err.Error()})
			c.Abort()
			return
		}

		c.Next()
	}
}
